﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Linq.Dynamic;
using System.Web;
using System.Web.Mvc;
using System.Linq.Expressions;
using MaymuseMS.Models;
using Zsnd.Helpers;

namespace MaymuseMS.DAL {
    public class GenericRepository<TEntity> where TEntity : class, new() {
        internal MaymuseMSContext context;
        internal DbSet<TEntity> dbSet;

        public virtual IQueryable<TEntity> GetDbSet() {
            return dbSet;
        }

        public GenericRepository(MaymuseMSContext context) {
            this.context = context;
            this.dbSet = context.Set<TEntity>();
        }
        public int Count() {
            return GetDbSet().Count();
        }

        //未分页query
        public virtual IQueryable<TEntity> Get(string sidx, string sord, string filters) {
            return Get(sidx, sord, filters, null);
        }
        //未分页query 带查询条件
        public virtual IQueryable<TEntity> Get(string sidx, string sord, string filters, Expression<Func<TEntity, bool>> predicate) {
            IQueryable<TEntity> query = GetDbSet();
            if (predicate != null) query = query.Where(predicate);
            if (!string.IsNullOrWhiteSpace(filters)) {
                FilterHelper<TEntity> filterHelper = new FilterHelper<TEntity>(query, filters);
                query = filterHelper.GetQuery();
            }
            query = query.OrderBy(sidx + " " + sord);
            return query;
        }

        public virtual IEnumerable<TEntity> Get(int pageIndex, int pageSize, string sidx, string sord, string filters) {
            return Get(pageIndex, pageSize, sidx, sord, filters, null);
        }

        public virtual IEnumerable<TEntity> Get(int pageIndex, int pageSize, string sidx, string sord, string filters, Expression<Func<TEntity, bool>> predicate) {
            var query = Get(sidx, sord, filters, predicate).Skip(pageIndex * pageSize).Take(pageSize);
            return query.ToList();
        }

        //单表，不涉及一对多关联表更新
        //public virtual IEnumerable<TEntity> Get(int pageIndex, int pageSize, string sidx, string sord, string filters) {
        //    double sum;
        //    return Get(pageIndex, pageSize, sidx, sord, filters, null, null, out sum);
        //}

        //public virtual IEnumerable<TEntity> Get(int pageIndex, int pageSize, string sidx, string sord, string filters, Expression<Func<TEntity, bool>> predicate) {
        //    double sum;
        //    return Get(pageIndex, pageSize, sidx, sord, filters, predicate, null, out sum);
        //}

        public virtual IEnumerable<TEntity> Get(int pageIndex, int pageSize, string sidx, string sord, string filters, Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, double>> predicate1, out double sum) {
            IQueryable<TEntity> query = GetDbSet();
            if (predicate != null) query = query.Where(predicate);
            if (!string.IsNullOrWhiteSpace(filters)) {
                FilterHelper<TEntity> filterHelper = new FilterHelper<TEntity>(query, filters);
                query = filterHelper.GetQuery();
            }
            query = query.OrderBy(sidx + " " + sord).Skip(pageIndex * pageSize).Take(pageSize);
            if (predicate1 != null && query.Count() > 0) {
                sum = query.Sum(predicate1);
            } else {
                sum = 0;
            }
            return query.ToList();
        }

        public virtual void Remove(string ids) {
            if (string.IsNullOrWhiteSpace(ids)) throw new ArgumentNullException("id为空");
            IList<int> idList = ids.ToIntList();
            if (idList == null || idList.Count < 1) throw new ArgumentNullException("id为空");
            foreach (int id in idList) {
                var n = dbSet.Find(id);
                if (n != null) {
                    dbSet.Remove(n);
                }
            }
        }

        public virtual TEntity Get(int id) {
            return dbSet.Find(id);
        }

        public virtual void Add(TEntity tEntity) {
            dbSet.Add(tEntity);
        }

        public virtual IEnumerable<TEntity> GetWithRawSql(string query, params object[] parameters) {
            return dbSet.SqlQuery(query, parameters).ToList();
        }
    }
}